package com.example.excel_db.validator;

import com.example.excel_db.entity.ExcelTemplate;
import com.example.excel_db.entity.ExcelTemplateField;
import com.example.excel_db.repository.ExcelTemplateFieldRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Excel数据校验器工厂
 * 用于创建和缓存校验器实例
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ExcelDataValidatorFactory {

    private final ApplicationContext applicationContext;
    private final ExcelTemplateFieldRepository fieldRepository;
    
    // 校验器缓存，键为模板ID
    private final Map<Long, ExcelDataValidator> validatorCache = new ConcurrentHashMap<>();

    /**
     * 获取指定模板的校验器
     *
     * @param template 模板对象
     * @return 校验器实例
     */
    public ExcelDataValidator getValidator(ExcelTemplate template) {
        return validatorCache.computeIfAbsent(template.getId(), id -> createValidator(template));
    }

    /**
     * 创建校验器实例
     *
     * @param template 模板对象
     * @return 校验器实例
     */
    private ExcelDataValidator createValidator(ExcelTemplate template) {
        List<ExcelTemplateField> fields = fieldRepository.findByTemplateOrderByOrderNumAsc(template);
        
        // 尝试查找自定义校验器
        String validatorClassName = null;
        for (ExcelTemplateField field : fields) {
            if (field.getValidator() != null && !field.getValidator().isEmpty()) {
                validatorClassName = field.getValidator();
                break;
            }
        }
        
        // 如果找到自定义校验器类名，尝试实例化
        if (validatorClassName != null && !validatorClassName.isEmpty()) {
            try {
                Class<?> validatorClass = Class.forName(validatorClassName);
                if (ExcelDataValidator.class.isAssignableFrom(validatorClass)) {
                    try {
                        // 尝试从Spring容器中获取
                        ExcelDataValidator validator = (ExcelDataValidator) applicationContext.getBean(validatorClass);
                        log.info("使用Spring容器中的校验器: {}", validatorClassName);
                        return validator;
                    } catch (Exception e) {
                        // 如果Spring容器中没有，尝试通过反射创建实例
                        try {
                            ExcelDataValidator validator = (ExcelDataValidator) validatorClass
                                    .getDeclaredConstructor(ExcelTemplate.class, List.class)
                                    .newInstance(template, fields);
                            log.info("通过反射创建校验器: {}", validatorClassName);
                            return validator;
                        } catch (Exception ex) {
                            log.error("无法创建校验器实例: {}", validatorClassName, ex);
                        }
                    }
                }
            } catch (ClassNotFoundException e) {
                log.error("找不到校验器类: {}", validatorClassName, e);
            }
        }
        
        // 如果没有找到自定义校验器或实例化失败，使用默认校验器
        log.info("使用默认校验器");
        return new DefaultExcelDataValidator(template, fields);
    }

    /**
     * 清除校验器缓存
     *
     * @param templateId 模板ID
     */
    public void clearCache(Long templateId) {
        validatorCache.remove(templateId);
    }

    /**
     * 清除所有校验器缓存
     */
    public void clearAllCache() {
        validatorCache.clear();
    }
}